package lumis.service.wsrp.consumer;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.xml.ws.Holder;

import lumis.portal.PortalException;

import com.sun.portal.wsrp.common.WSRPStubVersionConvertor;
import com.sun.portal.wsrp.common.stubs.V1ModelDescription;
import com.sun.portal.wsrp.common.stubs.V1PortletDescription;
import com.sun.portal.wsrp.common.stubs.V1Property;
import com.sun.portal.wsrp.common.stubs.WSRPV1PortletManagementPortType;
import com.sun.portal.wsrp.common.stubs.v2.PortletDescription;
import com.sun.portal.wsrp.common.stubs.v2.RegistrationContext;
import com.sun.portal.wsrp.consumer.common.RemoteServiceStubManagerFactory;
import com.sun.portal.wsrp.consumer.common.WSRPConsumerException;

/**
 * Remote portlet manager implementation for version 1.
 *
 * @version $Revision: 13092 $ $Date: 2011-05-28 18:19:06 -0300 (Sat, 28 May 2011) $
 * @since 6.0.0
 */
public class RemotePortletManagementManagerV1 implements RemotePortletManagementManager
{
	private URL producerURL;
	private RegistrationContext registrationContext;
	
	private WSRPV1PortletManagementPortType portletManagementPortType;
	
	public RemotePortletManagementManagerV1(URL producerURL, RegistrationContext registrationContext)
	{
		this.producerURL = producerURL;
		this.registrationContext = registrationContext;
	}
	
	/**
	 * Gets the WSRPV1PortletManagementPortType implementation.
	 * @return	an instance of WSRPV1PortletManagementPortType.
	 * @throws WSRPConsumerException 
	 */
	private WSRPV1PortletManagementPortType getPortletManagementImplementation() throws WSRPConsumerException
	{
		if (this.portletManagementPortType == null)
		{
			this.portletManagementPortType = RemoteServiceStubManagerFactory
												.getRemoteServiceStubManager()
													.getPortletManagementPortType(this.producerURL.toString());
		}
		return this.portletManagementPortType;
	}
	
	public String getPortletName(String portletHandle) throws PortalException
	{
		V1PortletDescription portletDescription = getPortletDescriptionV1(portletHandle);
		if (portletDescription.getDisplayName() != null)
		{
			return portletDescription.getDisplayName().getValue();
		}
		else
		{
			return null;
		}	
	}
	
	public String getDescriptionFromPortlet(String portletHandle)
					throws PortalException
	{
		V1PortletDescription portletDescription = getPortletDescriptionV1(portletHandle);
		if (portletDescription.getDescription() != null)
		{
			return portletDescription.getDescription().getValue();
		}
		else
		{
			return null;
		}		
	}
	
	public PortletDescription getPortletDescription(String portletHandle)
								throws PortalException
	{
		V1PortletDescription v1PortletDescription = getPortletDescriptionV1(portletHandle);		
		return WSRPStubVersionConvertor.getV2PortletDescription(v1PortletDescription);
	}
	
	private V1PortletDescription getPortletDescriptionV1(String portletHandle)
									throws PortalException
	{
		try
		{
			RemotePortletHelperV1 helper = new RemotePortletHelperV1(portletHandle, registrationContext);
			
			WSRPV1PortletManagementPortType type = getPortletManagementImplementation();
						
			Holder<V1PortletDescription> portletDescriptionHolder = helper.getEmptyPortletDescriptionHolderV1();
			
			type.getPortletDescription(
						helper.getRegistrationContextV1(),
						helper.getPortletContextV1(),
						helper.getEmptyUserContextV1(),
						new ArrayList<String>(),
						portletDescriptionHolder,
						helper.getEmptyResourceListHolderV1(),
						helper.getEmptyPortletExtensionsHolderV1());
			
			return portletDescriptionHolder.value;
			
		}
		catch (Exception e)
		{
			throw new PortalException("STR_WSRP_NOT_OBTAIN_PORTLET_DESCRIPTION;" + portletHandle , e);
		}
	}
	
	public String clonePortlet(String portletHandle)
					throws PortalException
	{
		try
		{
			RemotePortletHelperV1 helper = new RemotePortletHelperV1(portletHandle, registrationContext);
			
			Holder<String> phh = helper.getEmptyPortletHandleHolder();
			
			WSRPV1PortletManagementPortType type = getPortletManagementImplementation();
			type.clonePortlet(helper.getRegistrationContextV1(), 
								helper.getPortletContextV1(),
								helper.getEmptyUserContextV1(), 
								phh,
								helper.getEmptyPortletStateHolder(),
								helper.getEmptyPortletExtensionsHolderV1());
			
			return phh.value;
		}
		catch (Exception e)
		{
			throw new PortalException("STR_WSRP_NOT_CLONE_PORTLET;" + portletHandle , e);
		} 
	}

	public Properties getPortletProperties(
						String portletHandle)
					throws PortalException
	{
		try
		{
			RemotePortletHelperV1 helper = new RemotePortletHelperV1(portletHandle, registrationContext);
			
			Holder<List<V1Property>> v1Properties = helper.getEmptyPropertiesHolderV1();
			WSRPV1PortletManagementPortType type = getPortletManagementImplementation();
			type.getPortletProperties(helper.getRegistrationContextV1(),
										helper.getPortletContextV1(),
										helper.getEmptyUserContextV1(),
										null,
										v1Properties,
										helper.getEmptyResetPropertyListHolderV1(),
										helper.getEmptyPortletExtensionsHolderV1());
			
			Properties properties = RemotePortletHelperV1.toProperties(v1Properties);
			return properties;
		}
		catch (Exception e)
		{
			throw new PortalException("STR_WSRP_NOT_OBTAIN_PORTLET_PROPERTIES", e);
		}
	}


	public String getPortletPropertyDescription(
					String portletHandle,
					String propertyName)
				throws PortalException
	{
		try
		{
			RemotePortletHelperV1 helper = new RemotePortletHelperV1(portletHandle, registrationContext);
			Holder<V1ModelDescription> modelDescription = helper.getEmptyModelDescriptionHolderV1();
			
			WSRPV1PortletManagementPortType type = getPortletManagementImplementation();
			type.getPortletPropertyDescription(helper.getRegistrationContextV1(),
												helper.getPortletContextV1(),
												helper.getEmptyUserContextV1(),
												new ArrayList<String>(),
												modelDescription,
												helper.getEmptyResourceListHolderV1(),
												helper.getEmptyPortletExtensionsHolderV1());
			
			return RemotePortletHelperV1.toPropertyDescription(modelDescription, propertyName);
		}
		catch (Exception e)
		{
			throw new PortalException("STR_WSRP_NOT_OBTAIN_PROPERTY_FOR_PORTLET;" + propertyName + ";" + portletHandle , e);
		}		
	}

	public void removeClone(String portletHandle)
					throws PortalException
	{
		RemotePortletHelperV1 helper = new RemotePortletHelperV1(portletHandle, registrationContext);
		
		List<String> portletHandleList = new ArrayList<String>();
		portletHandleList.add(portletHandle);
		
		try
		{
			WSRPV1PortletManagementPortType type = getPortletManagementImplementation();
			type.destroyPortlets(helper.getRegistrationContextV1(),
									portletHandleList,
									helper.getEmptyDestroyFailedListHolderV1(),
									helper.getEmptyPortletExtensionsHolderV1());			
		}
		catch (Exception e)
		{
			throw new PortalException("STR_WSRP_NOT_REMOVE_CLONE;" + portletHandle, e);
		}		
	}

	public void setPortletProperties(
					String portletHandle,
					Properties properties)
				throws PortalException
	{
		RemotePortletHelperV1 helper = new RemotePortletHelperV1(portletHandle, registrationContext);
		
		try
		{
			WSRPV1PortletManagementPortType type = getPortletManagementImplementation();		
			type.setPortletProperties(helper.getRegistrationContextV1(),
										helper.getPortletContextV1(),
										helper.getEmptyUserContextV1(),
										RemotePortletHelperV1.toPropertyListV1(properties),
										helper.getEmptyPortletHandleHolder(),
										helper.getEmptyPortletStateHolder(),
										helper.getEmptyPortletExtensionsHolderV1());			
		}
		catch (Exception e)
		{
			throw new PortalException("STR_WSRP_NOT_CHANGE_PROPERTIES;" + portletHandle , e);
		}
	}
}